#include "ipsocket.h"
#include "ui_ipsocket.h"
#include <QDebug>

ipSocket::ipSocket(QWidget *parent) :
    isValic(false),ipSrcPort(0),ipDetPort(0),
    QDialog(parent),
    ui(new Ui::ipSocket)
{
    ui->setupUi(this);
    typeChange();
    connect(ui->pushButtonLink,SIGNAL(clicked(bool)),this,SLOT(ConfigSocket()));
    connect(ui->pushButtonSend,SIGNAL(clicked(bool)),this,SLOT(SendPackets()));
    connect(ui->comboBoxType,SIGNAL(currentIndexChanged(int)),this,SLOT(typeChange()));
}

ipSocket::~ipSocket()
{
    delete ui;
}

void ipSocket::typeChange(){
    int index=ui->comboBoxType->currentIndex();
    switch(index){
    case 0:type=TCPServer;ui->lineEditIP->setEnabled(false);break;
    case 1:type=TCPClient;ui->lineEditIP->setEnabled(true) ;break;
    case 2:type=UDPServer;ui->lineEditIP->setEnabled(false);break;
    case 3:type=UDPClient;ui->lineEditIP->setEnabled(true) ;break;
    }
}

void ipSocket::ConfigSocket(){
    switch(type){
    case TCPServer:
        if(!isValic){
            tcpServer = new QTcpServer;
            tcpSocket = new QTcpSocket;
            ipSrcPort = ui->lineEditPort->text().toInt();
            isValic=tcpServer->listen(QHostAddress::Any,ipSrcPort);
            if(!isValic){
                QMessageBox::information(this,"error","socket listen error!","ok");
                delete tcpServer;
                delete tcpSocket;
            }
            else connect(tcpServer,SIGNAL(newConnection()),this,SLOT(NewConnect()));
        }
        else{
            isValic=false;
            tcpSocket->disconnected();
            tcpServer->close();
            disconnect(tcpSocket);
            delete tcpSocket;
            delete tcpServer;
        }
        break;
    case TCPClient:
        if(!isValic){
            tcpSocket = new QTcpSocket;
            ipDetPort = ui->lineEditPort->text().toInt();
            ipAddr = QHostAddress(ui->lineEditIP->text());
            tcpSocket->connectToHost(ipAddr, ipDetPort);
            if(!tcpSocket->waitForConnected(1000)){
                QMessageBox::information(this,"error","connection failed!","ok");
                delete tcpSocket;
            }
            else{
                isValic=true;
                connect(tcpSocket, SIGNAL(readyRead()),this, SLOT(RecvPackets()));
                connect(tcpSocket, SIGNAL(disconnected()),this, SLOT(DisConnect()));
                qDebug()<<"sss";
            }
        }
        else{
            isValic=false;
            tcpSocket->disconnectFromHost();
            disconnect(tcpSocket);
            delete tcpSocket;
            break;
        }
        break;
    case UDPServer:
        if(!isValic){
            udpSocket = new QUdpSocket;
            ipSrcPort = ui->lineEditPort->text().toInt();
            isValic = udpSocket->bind(ipSrcPort);
            if(!isValic){
                QMessageBox::information(this,"error","socket bind error!","ok");
                delete udpSocket;
            }
            else connect(udpSocket, SIGNAL(readyRead()),this, SLOT(RecvPackets()));
        }
        else{
            isValic=false;
            disconnect(udpSocket);
            delete udpSocket;
        }
        break;
    case UDPClient:
        if(!isValic){
            udpSocket = new QUdpSocket;
            ipDetPort = ui->lineEditPort->text().toInt();
            ipAddr = QHostAddress(ui->lineEditIP->text());
            isValic = true;
        }
        else{
            isValic=false;
            disconnect(udpSocket);
            delete udpSocket;
            break;
        }
        break;
    }

    if(isValic){
        ui->pushButtonLink->setText("unlink");
        ui->comboBoxType->setEnabled(false);
        ui->pushButtonSend->setEnabled(true);
        ui->lineEditPort->setEnabled(false);
        ui->lineEditIP->setEnabled(false);
    }
    else{
        ui->pushButtonLink->setText("link");
        ui->comboBoxType->setEnabled(true);
        ui->pushButtonSend->setEnabled(false);
        ui->lineEditPort->setEnabled(true);
        if(type==TCPClient||type==UDPClient)ui->lineEditIP->setEnabled(true);
    }
}

void ipSocket::NewConnect(void){
    tcpSocket = tcpServer->nextPendingConnection();
    connect(tcpSocket, SIGNAL(readyRead()),this, SLOT(RecvPackets()));
}

void ipSocket::DisConnect(void){
    isValic = false;
    ui->pushButtonLink->setText("link");
    ui->comboBoxType->setEnabled(true);
    ui->pushButtonSend->setEnabled(false);
}

void ipSocket::RecvPackets(){
    dataRx.clear();
    switch(type){
    case TCPServer://tcpServer
        dataRx=tcpSocket->readAll();
        ui->textEditRcv->append(dataRx);
        break;
    case TCPClient://tcpClient
        dataRx=tcpSocket->readAll();
        ui->textEditRcv->append(dataRx);
        break;
    case UDPServer://updServer
        dataRx.resize(udpSocket->pendingDatagramSize());
        udpSocket->readDatagram(dataRx.data(), dataRx.size(),&ipAddr,&ipDetPort);
        ui->textEditRcv->append(dataRx);
        break;
    case UDPClient://udpClient
        dataRx.resize(udpSocket->pendingDatagramSize());
        udpSocket->readDatagram(dataRx.data(), dataRx.size(),NULL,NULL);
        ui->textEditRcv->append(dataRx);
        break;
    }
    emit ReadyRecv(dataRx);
}

void ipSocket::SendPackets(){
    dataTx.clear();
    dataTx = ui->lineEditSnd->text().toLatin1();
    SendPackets(dataTx);
}

void ipSocket::SendPackets(QByteArray &data){
    if(!isValic){
        QMessageBox::information(this,"error","connect failed!","ok");
        return;
    }
    switch(type){
    case TCPServer://tcpServer
        tcpSocket->write(data);
        break;
    case TCPClient://tcpClient
        tcpSocket->write(data);
        break;
    case UDPServer://updServer
        udpSocket->writeDatagram(data, data.size(), ipAddr, ipDetPort);
        break;
    case UDPClient://udpClient
        udpSocket->writeDatagram(data, data.size(), ipAddr, ipDetPort);
        if(udpSocket->localPort()!=ipSrcPort){
            ipSrcPort = udpSocket->localPort();
            connect(udpSocket, SIGNAL(readyRead()),this, SLOT(RecvPackets()));
        }
        break;
    }
}
